﻿using BootstrapBlazor.Components;
using CodeMan.Application.Contracts.ClassGens;
using CodeMan.Domain.ClassGens;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.ObjectMapping;

using System.Linq;
using CodeMan.Domain.Shared.Enums;

namespace CodeMan.Application.ClassGens
{
    public class ClassGenAppService : IClassGenAppService
    {
        private IClassGenBlazorUIRepository _repository;
        private IObjectMapper ObjectMapper;
        private readonly ILogger _logger;

        private ClassGenDTOCreateUpdate? Model { get; set; }

        public ClassGenAppService(IClassGenBlazorUIRepository repository,
            IObjectMapper objectMapper,
            ILogger<ClassGenAppService> logger)
        {
            _repository = repository;
            ObjectMapper = objectMapper;
            _logger = logger;
        }

        public async Task<bool> AddAsync(ClassGenDTOCreateUpdate model)
        {
            Model = model;

            var saveItem = ObjectMapper.Map<ClassGenDTOCreateUpdate, ClassGen>(model);

            await _repository.AddAsync(saveItem);

            return true;
        }

        public async Task CancelAsync()
        {
            await _repository.CancelAsync();
        }

        public Task<bool> DeleteAsync(IEnumerable<ClassGenDTOCreateUpdate> models)
        {

            var dels = ObjectMapper.Map<IEnumerable<ClassGenDTOCreateUpdate>, IEnumerable<ClassGen>>(models);
            return _repository.DeleteAsync(dels);
        }

        public Task EditAsync(object model)
        {
            var dtomodel = model as ClassGenDTOCreateUpdate;
            var editmodel = ObjectMapper.Map<ClassGenDTOCreateUpdate, ClassGen>(dtomodel);
            return _repository.EditAsync(editmodel);
        }

        public async Task<QueryData<ClassGenDTOCreateUpdate>> QueryAsync(QueryPageOptions option)
        {

            var result = await _repository.QueryAsync(option);

            var tomaps = new List<ClassGenDTOCreateUpdate>();
            foreach (ClassGen item in result.Items)
            {
                tomaps.Add(ObjectMapper.Map<ClassGen, ClassGenDTOCreateUpdate>(
                    item));
            }

            // 注意：未处理搜索，此处设置 IsSearched=true 后会导致高级搜索按钮高亮
            var ret = new QueryData<ClassGenDTOCreateUpdate>()
            {
                TotalCount = result.TotalCount,
                Items = tomaps,
                IsSorted = result.IsSorted,
                IsFiltered = result.IsFiltered
            };
            return ret;
        }

        public async Task<bool> SaveAsync(ClassGenDTOCreateUpdate model, ItemChangedType changedType)
        {
            var saveItem = ObjectMapper.Map<ClassGenDTOCreateUpdate, ClassGen>(model);
            await _repository.SaveAsync(saveItem, changedType);
            return true;
        }
        public async Task SaveClassAndAtt(ClassGenDTOCreateUpdate classGen, List<ClassAttributeDTO> classAttributes)
        {
            var saveItem = ObjectMapper.Map<ClassGenDTOCreateUpdate, ClassGen>(classGen);
            var ilst = ObjectMapper.Map<List<ClassAttributeDTO>, List<ClassAttribute>>(classAttributes);
            await _repository.SaveClassAndAtt(saveItem, ilst);

        }
        public async Task<IReadOnlyList<TreeItem>> GetTreeItemsAsync(Int64 tkey)
        {
            var result = new List<TreeItem>();
            IReadOnlyList<ClassGen> getAllClassGen;
            IReadOnlyList<ClassAttribute> getAllClassAttr;

            if (tkey <= 0)
            {
                getAllClassGen = await _repository.GetClassGensAllAsync();
                getAllClassAttr = await _repository.GetClassAttributesAllAsync();
            }
            else
            {
                getAllClassGen = await _repository.GetClassGensAsync(tkey);
                getAllClassAttr = await _repository.GetClassAttributesAsync(tkey);
            }

            foreach (var item in getAllClassGen)
            {
                var currDto = ObjectMapper.Map<ClassGen, ClassGenDTOCreateUpdate>(item);
                currDto.FromType = FromTypeEnum.localDB;
                //类、表
                var ptreeitem = new TreeItem() { Text = currDto.Name, Key = $"table_0_{item.Id}", HasChildNode = true, Tag = currDto, IsDisabled = false };

                if (tkey > 0)
                {
                    var resultClass = new List<TreeItem>();
                    resultClass.Add(new TreeItem() { Text = currDto.Desc, IsDisabled = true });
                    resultClass.Add(new TreeItem() { Text = $"Namespace:{currDto.Namespace}", IsDisabled = true });
                    resultClass.Add(new TreeItem() { Text = $"Type:{currDto.Type}", IsDisabled = true });
                    //字段,属性
                    var attrTreimte = new TreeItem() { Text = "字段明细", IsDisabled = true };
                    var getDetails = getAllClassAttr.Where(a => a.ClassGenId == currDto.Id);
                    foreach (var itemList in getDetails)
                    {
                        var ilst = ObjectMapper.Map<ClassAttribute, ClassAttributeDTO>(itemList);
                        var currlist = new TreeItem() { Text = ilst.AName, Key = $"{ currDto.Id}_{ilst.AName}", Tag = ilst, IsDisabled = true };

                        currlist.AddItem(new TreeItem() { Text = ilst.ADesc, IsDisabled = true });
                        currlist.AddItem(new TreeItem() { Text = $"IsKey:{ilst.IsKey}", IsDisabled = true });
                        currlist.AddItem(new TreeItem() { Text = $"Type:{ilst.AType}", IsDisabled = true });
                        currlist.AddItem(new TreeItem() { Text = $"Length:{ilst.Length}", IsDisabled = true });
                        currlist.AddItem(new TreeItem() { Text = $"defaultValue:{ilst.defaultValue}", IsDisabled = true });
                        currlist.AddItem(new TreeItem() { Text = $"IsAutoGenerate:{ilst.IsAutoGenerate}", IsDisabled = true });
                        currlist.AddItem(new TreeItem() { Text = $"IsShow:{ilst.IsShow}", IsDisabled = true });

                        attrTreimte.AddItem(currlist);
                    }

                    resultClass.Add(attrTreimte);

                    return resultClass;
                }

                result.Add(ptreeitem);
            }
            return result;
        }
    }
}
